淺談一個關於標註的商業邏輯
今天一個圖片內有N個標註,需要將其轉為YOLO格式
image
label
bussiness_logic.py
def fetch_and_format_labels():
image = fetch_image_info()
labels = fetch_labels_info()
label_formater.py
def yolo(image_width, image_height, labels_coordniate):
# implement yolo logic
今天又有另外一個商業邏輯要將標注轉為PascalXML
所以程式必須改為
bussiness_logic.py
def fetch_and_format_labels():
image = fetch_image_info()
labels = fetch_labels_info()
return [label_formater.yolo(image['width'], image['height'], label['coordniates']) for label in labels]
bussiness_logic1.py
def fetch_and_format_labels():
image = fetch_image_info()
labels = fetch_labels_info()
return [label_formater.pascal(image['path'], image['width'], image['height'], image['depth'], label['coordniates']) for label in labels]
label_formater.py
def yolo(image_width, image_height, labels_coordniate):
# implement yolo logic
def pascalXML(path, image_width, image_height, image_depth, labels_coordniate):
# implement yolo logic
問題來了
今天如果又要支援其他格式,例如coco,開發商業邏輯的就需要知道coco應該傳哪些參數
今天如果bussiness_logic1要改成支援Yolo、是否還要改動參數呢?
如果要開發一個商業邏輯4,開發者還要去找到該傳哪些參數
也就是說商業邏輯跟formatter產生了依賴性
這邊其實同時違反了里氏替換原則跟控制反轉
更簡單的理解就是商業邏輯需要知道底層如何實作,儘管這顯然不是商業邏輯的責任
當然在動態語言如Python,我們可以簡單把東西全部丟到dict like
def fetch_and_format_labels():
image = fetch_image_info()
labels = fetch_labels_info()
return [label_formater.pascal(image, label) for label in labels]
label_formater.py
def yolo(image, labelimage):
# implement yolo logic
def pascalXML(image, label):
# implement yolo logic
看起來沒問題了,對吧?
於是今天下一個改動是要支援Coco
coco formater的開發者要怎麼知道image, label有哪些參數呢?
他只能回去看bussiness實作來猜
這其實一樣違反依賴反轉,依賴反轉是需要雙方依賴於介面而非彼此
那問題來了 怎麼辦呢?
這時候就要請出DTO來
設兩個Dto:
dto.py
@dataclass
class Image:
labels: List[Label]
path = ''
width = 0
height = 0
depth = 3
@dataclass
class Label:
coordniates: List[List[float]] = field(default_factory=list
tag = ''
此時
def yolo(image: Image):
labels = image.labels
# implement yolo logic
def pascalXML(image: Image):
labels = image.labels
# implement yolo logic
business logic只需要負責把image丟進formatter
而formatter只需要知道dto長什麼樣子,跟business logic到底怎麼拿到,如何組出來都跟formatter無關
在一個多人開發,持續維護的架構中,如果有一堆參數有一個明顯的歸屬class
而且這個class很多都module都需要用,就要考慮訂一個DTO來處理
可以減少很多溝通上的成本,也可以少寫很多文件